package es.upv.tricia.activity;

import java.util.List;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import es.upv.tricia.HighScore;
import es.upv.tricia.HighScoreList;
import es.upv.tricia.R;
import es.upv.tricia.Tricia;
import es.upv.tricia.rest.GsonHttpResponseHandler;
import es.upv.tricia.rest.RequestParams;
import es.upv.tricia.rest.RestClient;
import es.upv.tricia.util.HighScoreReader;

public class ScoresActivity extends Activity implements OnTabChangeListener
{
	private TableLayout mLocalTable, mFriendsTable;

	private String mEmail;

	private TabHost mTabHost;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.scores);

		SharedPreferences settings = getSharedPreferences(
				Tricia.SETTINGS_PREFS_NAME, MODE_PRIVATE);

		mEmail = settings.getString("email", "");

		mTabHost = (TabHost) findViewById(R.id.scoresTabHost);
		mTabHost.setup();
		Resources resources = getResources();
		TabHost.TabSpec spec;

		spec = mTabHost.newTabSpec("localScores");
		spec.setIndicator(resources.getText(R.string.localUsers),
				resources.getDrawable(R.drawable.icon));
		spec.setContent(R.id.localScores);
		mTabHost.addTab(spec);

		spec = mTabHost.newTabSpec("friendsScores");
		spec.setIndicator(resources.getText(R.string.usersFriends),
				resources.getDrawable(R.drawable.icon));
		spec.setContent(R.id.friendsScores);
		mTabHost.addTab(spec);

		mTabHost.setCurrentTab(savedInstanceState != null ? savedInstanceState
				.getInt("currentTab", 0) : 0);
		mTabHost.setOnTabChangedListener(this);

		if (mTabHost.getCurrentTab() == 0) {
			loadLocalScores();
		} else {
			loadFriendsScores();
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState)
	{
		super.onSaveInstanceState(outState);

		outState.putInt("currentTab", mTabHost.getCurrentTab());
	}

	private void loadLocalScores()
	{
		mLocalTable = (TableLayout) findViewById(R.id.localScoresTable);
		mLocalTable.removeAllViews();
		mLocalTable.addView(newHeaderRow());

		new LocalScoresLoader().execute();
	}

	private void loadFriendsScores()
	{
		mFriendsTable = (TableLayout) findViewById(R.id.friendsScoresTable);
		mFriendsTable.removeAllViews();
		mFriendsTable.addView(newHeaderRow());

		RequestParams params = new RequestParams();
		params.put("email", mEmail);
		RestClient.get("highscores", params, new FriendsScoresLoader());
	}

	@Override
	public void onTabChanged(String tabId)
	{
		if (mLocalTable == null && tabId == "localScores") {
			loadLocalScores();

		}
		if (mFriendsTable == null && tabId == "friendsScores") {
			loadFriendsScores();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		getMenuInflater().inflate(R.menu.scores, menu);

		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu)
	{
		return mTabHost.getCurrentTab() == 0;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		new LocalScoresDeleter().execute();

		return true;
	}

	private TableRow newHeaderRow()
	{
		TableRow row;
		TextView tv;

		row = new TableRow(this);

		tv = new TextView(this);
		tv.setText("User");
		tv.setTextAppearance(getApplicationContext(), R.style.boldText);
		row.addView(tv);

		tv = new TextView(this);
		tv.setText("Score");
		tv.setTextAppearance(getApplicationContext(), R.style.boldText);
		row.addView(tv);

		tv = new TextView(this);
		tv.setTextAppearance(getApplicationContext(), R.style.boldText);
		tv.setText("Rank");
		row.addView(tv);

		return row;
	}

	private TableRow newHighScoreRow(HighScore highScore, int rank)
	{
		TableRow row;
		TextView tv;

		row = new TableRow(getBaseContext());

		tv = new TextView(getBaseContext());
		tv.setText(highScore.getUsername());
		row.addView(tv);

		tv = new TextView(getBaseContext());
		tv.setText(Integer.toString(highScore.getScore()));
		row.addView(tv);

		tv = new TextView(getBaseContext());
		tv.setText(Integer.toString(rank));
		row.addView(tv);

		return row;
	}

	private final class FriendsScoresLoader extends
			GsonHttpResponseHandler<HighScoreList>
	{
		private FriendsScoresLoader()
		{
			super(HighScoreList.class);
		}

		@Override
		public void onStart()
		{
			setProgressBarIndeterminate(true);
			setProgressBarIndeterminateVisibility(true);
		}

		@Override
		public void onFinish()
		{
			setProgressBarIndeterminateVisibility(false);
		}

		@Override
		public void onSuccess(HighScoreList highScoreList)
		{
			List<HighScore> highScores = highScoreList.asSortedList();

			int i = 1;

			for (HighScore highScore : highScores) {
				mFriendsTable.addView(newHighScoreRow(highScore, i++));
			}
		}
	}

	private final class LocalScoresLoader extends
			AsyncTask<Void, HighScoreList, Boolean>
	{
		@Override
		protected Boolean doInBackground(Void... params)
		{
			publishProgress(HighScoreReader.loadHighScores(getBaseContext()));

			return null;
		}

		@Override
		protected void onProgressUpdate(HighScoreList... highScoreLists)
		{
			super.onProgressUpdate(highScoreLists);

			int i = 1;

			for (HighScoreList highScoreList : highScoreLists) {
				List<HighScore> highScores = highScoreList.asSortedList();

				for (HighScore highScore : highScores) {
					mLocalTable.addView(newHighScoreRow(highScore, i++));
				}
			}
		}

		@Override
		protected void onPreExecute()
		{
			setProgressBarIndeterminate(true);
			setProgressBarIndeterminateVisibility(true);
		}

		@Override
		protected void onPostExecute(Boolean result)
		{
			setProgressBarIndeterminateVisibility(false);
		}
	}

	private final class LocalScoresDeleter extends AsyncTask<Void, Void, Void>
	{
		@Override
		protected Void doInBackground(Void... params)
		{
			HighScoreReader.saveHighScores(getBaseContext(), new HighScoreList());

			publishProgress();

			return null;
		}

		@Override
		protected void onProgressUpdate(Void... values)
		{
			mLocalTable = (TableLayout) findViewById(R.id.localScoresTable);
			mLocalTable.removeAllViews();
			mLocalTable.addView(newHeaderRow());
		}

		@Override
		protected void onPreExecute()
		{
			setProgressBarIndeterminate(true);
			setProgressBarIndeterminateVisibility(true);
		}

		@Override
		protected void onPostExecute(Void result)
		{
			setProgressBarIndeterminateVisibility(false);
		}
	}
}
